// 引入必要的命名空间
using BCrypt.Net;
using UniversalAdmin.Application.DTOs; // 引入数据传输对象定义
using UniversalAdmin.Domain.Entities;
using UniversalAdmin.Domain.Repositories; // 引入仓储接口
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace UniversalAdmin.Application.Services;

// 用户服务类，实现IUserService接口
public class UserService : IUserService
{
    // 用户仓储实例
    private readonly IUserRepository _userRepository;
    private readonly IRoleRepository _roleRepository;

    // 构造函数，注入用户仓储
    public UserService(IUserRepository userRepository, IRoleRepository roleRepository)
    {
        _userRepository = userRepository; // 初始化用户仓储
        _roleRepository = roleRepository; // 初始化角色仓储
    }
    //分页
    public async Task<PagedResultDto<UserDto>> GetUsersAsync(int page, int pageSize)
    {
        var (users, total) = await _userRepository.GetPagedAsync(page, pageSize);
        var items = users.Select(u => new UserDto(u.Id, u.Username, u.Email ?? "", u.PhoneNumber, new List<RoleDto>())).ToList();

        return new PagedResultDto<UserDto>
        {
            Items = items,
            TotalCount = total,
            Page = page,
            PageSize = pageSize
        };
    }

    // 根据用户ID获取用户信息
    public async Task<UserDto?> GetUserByIdAsync(Guid id)
    {
        // 异步查询数据库中匹配ID的用户，包含角色信息
        var user = await _userRepository.GetByIdWithRolesAsync(id);
        if (user == null)
            throw new Exception("用户不存在"); // 用户不存在时抛出异常

        // 返回用户数据传输对象
        return new UserDto(
            user.Id,
            user.Username, // 用户名
            user.Email ?? "",    // 用户邮箱
            user.PhoneNumber, // 用户电话号码
            user.Roles.Select(r => new RoleDto(r.Id, r.Name ?? "", r.Description)).ToList() // 角色信息
        );
    }

    // 根据关键字搜索用户
    public async Task<List<UserDto>> SearchUsersAsync(string keyword)
    {
        // 检查关键字是否为空或空白
        if (string.IsNullOrWhiteSpace(keyword))
            throw new Exception("关键字不能为空"); // 抛出异常

        // 使用仓储的分页方法来搜索用户
        var (users, _) = await _userRepository.GetPagedAsync(1, 20, keyword);

        // 将查询结果转换为UserDto列表
        return users.Select(u => new UserDto(
            u.Id,
            u.Username, // 用户名
            u.Email ?? "",    // 用户邮箱
            u.PhoneNumber, // 用户电话号码
            new List<RoleDto>() // 角色信息（搜索时不包含角色）
        )).ToList();
    }

    // 更新用户信息
    public async Task<UserDto?> UpdateUserAsync(Guid id, UpdateUserDto dto)
    {
        // 查询数据库中匹配ID的用户
        var user = await _userRepository.GetByIdAsync(id);
        if (user == null)
            throw new Exception("用户不存在"); // 用户不存在时抛出异常

        // 更新用户信息
        user.Username = dto.Username; // 更新用户名
        user.Email = dto.Email;      // 更新用户邮箱
        user.PhoneNumber = dto.PhoneNumber; // 更新用户电话号码

        // 保存更改到数据库
        await _userRepository.UpdateAsync(user);

        // 返回更新后的用户数据传输对象
        return new UserDto(
            user.Id,
            user.Username, // 用户名
            user.Email,    // 用户邮箱
            user.PhoneNumber, // 用户电话号码
            new List<RoleDto>() // 角色信息（更新时不包含角色）
        );
    }

    // 创建用户
public async Task<UserDto> CreateUserAsync(CreateUserDto dto)
{
    // 检查用户名是否已存在
    if (await _userRepository.ExistsByUsernameAsync(dto.Username))
        throw new Exception("用户名已存在");

    // 检查邮箱是否已存在
    if (await _userRepository.ExistsByEmailAsync(dto.Email))
        throw new Exception("邮箱已存在");

    // 创建新用户
    var user = new User
    {
        Id = Guid.NewGuid(),
        Username = dto.Username,
        Email = dto.Email,
        PhoneNumber = dto.PhoneNumber,
        PasswordHash = BCrypt.Net.BCrypt.HashPassword(dto.Password) // 使用BCrypt加密密码
    };

    // 添加到数据库
    await _userRepository.AddAsync(user);

    // 返回创建的用户数据传输对象
    return new UserDto(
        user.Id,
        user.Username,
        user.Email ?? "",
        user.PhoneNumber,
        new List<RoleDto>()
    );
}

    // 删除用户
    public async Task<bool> DeleteUserAsync(Guid id)
    {
        // 查询数据库中匹配ID的用户
        var user = await _userRepository.GetByIdAsync(id);
        if (user == null)
            throw new Exception("用户不存在"); // 用户不存在时抛出异常

        // 从数据库中删除用户
        await _userRepository.DeleteAsync(user);

        return true; // 返回删除成功
    }

    // 获取用户角色
    public async Task<List<RoleDto>> GetUserRolesAsync(Guid userId)
    {
        // 查询数据库中匹配ID的用户
        var user = await _userRepository.GetByIdAsync(userId);
        if (user == null)
            throw new Exception("用户不存在"); // 用户不存在时抛出异常

        // 查询用户的角色信息
        var roles = await _roleRepository.GetRolesByUserAsync(userId);

        // 将Role实体转换为RoleDto
        return roles.Select(r => new RoleDto(r.Id, r.Name ?? "", r.Description)).ToList(); // 返回角色列表
    }

    // 为用户分配角色
    public async Task AssignRolesToUserAsync(Guid userId, List<Guid> roleIds)
    {
        // 查询数据库中匹配ID的用户
        var user = await _userRepository.GetByIdAsync(userId);
        if (user == null)
            throw new Exception("用户不存在"); // 用户不存在时抛出异常

        // 使用仓储接口为用户分配角色
        await _roleRepository.AssignRolesToUserAsync(userId, roleIds);
    }

    // 获取用户的所有权限
    public async Task<IEnumerable<PermissionDto>> GetUserPermissionsAsync(Guid userId)
    {
        // 查询数据库中匹配ID的用户
        var user = await _userRepository.GetByIdAsync(userId);
        if (user == null)
            throw new Exception("用户不存在"); // 用户不存在时抛出异常

        // 查询用户的权限信息
        var permissions = await _roleRepository.GetUserPermissionsAsync(userId);

        // 将Permission实体转换为PermissionDto
        return permissions.Select(p => new PermissionDto(
            p.Id,
            p.Name,
            p.Description,
            p.Resource,
            p.Action,
            p.Type,
            p.SortOrder,
            p.IsEnabled
        )).ToList(); // 返回权限列表
    }

    // 检查用户是否有特定权限
    public async Task<bool> UserHasPermissionAsync(Guid userId, string resource, string action)
    {
        // 查询数据库中匹配ID的用户
        var user = await _userRepository.GetByIdAsync(userId);
        if (user == null)
            throw new Exception("用户不存在"); // 用户不存在时抛出异常

        // 检查用户是否有特定权限
        var hasPermission = await _roleRepository.UserHasPermissionAsync(userId, resource, action);

        return hasPermission; // 返回权限检查结果
    }
}